import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Title      : MutipleChoiceGUI.java
 * Description: This class contains the implement of a program for MultipleChoice Questions.
 * Copyright  : Copyright (c) 2006-2018
 *
 * @author Jianlei Xu
 * @version 1.0
 */

public class MultiChoiceGui extends JFrame implements ActionListener {

    int nMode = 0;


    int[] scoreArray = new int[]{1, 2, 3};//  first
    int[] score2Array = new int[]{0, 1, 0};//  second


    String[] allQuestionArray;
    String[] allCorrectArray;
    String[] allAnswerArray;


    String[] questionArray;
    String[] answerArray;
    String[] correctArray;

    int nQ;
    int nscore = 0;
    int clickTime = 0;

    String S;

    JButton reset = new JButton("reset score");//Add a button to reset score
    JLabel score = new JLabel("score=" + nscore);//Add a label to display score
    JPanel pscore = new JPanel();//Add a panel to contain the score label
    JPanel bottom = new JPanel();//Add a panel for the bottom part
    JPanel cPanel = new JPanel();//Add a panel for the center part
    JLabel Question = new JLabel();//Add a label for the question
    JPanel lastPanel = new JPanel();
    JLabel finish = new JLabel("Your total score is " + nscore + ".");

    //Add an ArrayList for the four answer buttons
    ArrayList<JButton> BList = new ArrayList<JButton>();
    JButton A1 = new JButton();
    JButton A2 = new JButton();
    JButton A3 = new JButton();
    JButton A4 = new JButton();

    JButton B1 = new JButton("EASY");
    JButton B2 = new JButton("MEDIUM");
    JButton B3 = new JButton("DIFFICULT");

    JPanel modelPanel = new JPanel();

    {
        BList.add(A1);
        BList.add(A2);
        BList.add(A3);
        BList.add(A4);
    }


    //set the font
    Font bigFont = new Font("serif", Font.BOLD, 20);

    Object[] buttonRowObjects_ = new Object[]{
            "OK"
    };


    //init files
    private static final String QUESTION_PATH = "../files/question.txt";
    private static final String ANSWER_PATH = "../files/answer.txt";
    private static final String CORRECT_PATH = "../files/correct.txt";


    /**
     * Get question answer Correct from File
     *
     * @param path path of txt
     * @return Problem set
     */
    private String[] getDataFromFile(String path) {

        StringBuilder result = new StringBuilder();

        try {
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(path));
            byte[] bytes = new byte[2048];
            int n;
            while ((n = in.read(bytes, 0, bytes.length)) != -1) {
                String str = new String(bytes, 0, n, StandardCharsets.UTF_8);
                result.append(str);
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString().split(",");
    }


    /**
     * This is default constructor for MultipleChoiceGUI class.
     */
    public MultiChoiceGui() {
        super("Multiple Choice Questions");

        allQuestionArray = getDataFromFile(QUESTION_PATH);
        allCorrectArray = getDataFromFile(CORRECT_PATH);
        allAnswerArray = getDataFromFile(ANSWER_PATH);


        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(550, 400);
        setLayout(new BorderLayout());
        //set font for the question
        Question.setFont(bigFont);
        //initResultUI();
        initQuestionUI();
        initModelUI();
        bottom.setVisible(false);
        Question.setVisible(false);
        modelPanel.setVisible(true);
        setVisible(true);
    }

    /**
     * This is the initializes level set GUI
     */
    private void initModelUI() {
        modelPanel.setLayout(new GridLayout(3, 1, 10, 10));
        modelPanel.add(B1);
        modelPanel.add(B2);
        modelPanel.add(B3);
        B1.addActionListener(this);
        B2.addActionListener(this);
        B3.addActionListener(this);
        add(modelPanel, BorderLayout.CENTER);
    }


    /**
     * This is the initializes Question set GUI
     */
    private void initQuestionUI() {
        //add panels to the frame
        pscore.add(score);
        bottom.add(pscore);
        bottom.add(reset);
        add(bottom, BorderLayout.SOUTH);
        add(Question, BorderLayout.NORTH);

        //add four answer button to the center panel
        cPanel.setLayout(new GridLayout(5, 1, 10, 10));
        cPanel.add(A1);
        cPanel.add(A2);
        cPanel.add(A3);
        cPanel.add(A4);

        //set border for the center part
        TitledBorder tb = BorderFactory.createTitledBorder(null, "Possible Answers:click one",
                TitledBorder.ABOVE_BOTTOM, TitledBorder.TOP,
                new Font("Dialog", Font.BOLD, 12), Color.black);
        cPanel.setBorder(tb);
        A1.addActionListener(this);
        A2.addActionListener(this);
        A3.addActionListener(this);
        A4.addActionListener(this);

        reset.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                nscore = 0;
                clickTime = 0;
                score.setText("score=0");
                lastPanel.setVisible(false);
                remove(lastPanel);
                remove(cPanel);
                bottom.setVisible(false);
                Question.setVisible(false);
                add(modelPanel, BorderLayout.CENTER);
                modelPanel.setVisible(true);
//                initData();
                //add(modelPanel);
                //initModelUI();
            }
        });
    }


    /**
     * This is the entrance of the program.
     */
    public static void main(String[] args) {
        new MultiChoiceGui();
    }

    /**
     * This is the method for the initial data
     */
    private void initData() {


        nQ = 0;
        Question.setText("Question" + (nQ + 1) + " of " + questionArray.length + ": " + questionArray[nQ]);
        String[] answer = answerArray[nQ].split("_");
        A1.setText(answer[0]);
        A2.setText(answer[1]);
        A3.setText(answer[2]);
        A4.setText(answer[3]);

    }

    /**
     * This method changes the problems
     */
    public void changePro(boolean isRight) {
//        if (clickTime == 2 && isRight) {
//            nscore = nscore - 1;
//        }

        clickTime = 0;
        score.setText("score=" + nscore);
        int size = answerArray.length;
        nQ = nQ + 1;

        System.out.println("nQ: " + nQ + ",size: " + size);
        if (nQ >= size) {
            initResultUI();
        } else {
            Question.setText("Question" + (nQ + 1) + " of " + questionArray.length + ": " + questionArray[nQ]);
            String[] answer = answerArray[nQ].split("_");
            A1.setText(answer[0]);
            A2.setText(answer[1]);
            A3.setText(answer[2]);
            A4.setText(answer[3]);
        }

    }

    private void totalScore(Object resouse) {
        System.out.println("nQ" + (nQ) + "," + questionArray.length);
        if (nQ > questionArray.length - 1) {
            return;
        }
        clickTime++;

        int scoreCurrent = 0;

        if (clickTime == 1) {
            switch (nMode) {
                case 0:
                    scoreCurrent = scoreArray[0];
                    break;
                case 1:
                    scoreCurrent = scoreArray[1];
                    break;
                case 2:
                    scoreCurrent = scoreArray[2];
                    break;
            }
        } else {
            switch (nMode) {
                case 0:
                    scoreCurrent = score2Array[0];
                    break;
                case 1:
                    scoreCurrent = score2Array[1];
                    break;
                case 2:
                    scoreCurrent = score2Array[2];
                    break;
            }
        }
        System.out.println("--->" + A1.getText().trim() + "," + correctArray[nQ]);
        if (resouse == A1) {
            if (A1.getText().trim().equals(correctArray[nQ])) {
                nscore = nscore + scoreCurrent;
                changePro(true);
            } else {
                JOptionPane.showOptionDialog(null, "Your answer is wrong", "Oops", JOptionPane.OK_OPTION, JOptionPane.WARNING_MESSAGE, null,
                        buttonRowObjects_,
                        null);
            }
        } else if (resouse == A2) {
            if (A2.getText().trim().equals(correctArray[nQ])) {
                nscore = nscore + scoreCurrent;
                changePro(true);
            } else {
                JOptionPane.showOptionDialog(null, "Your answer is wrong", "Oops", JOptionPane.OK_OPTION, JOptionPane.WARNING_MESSAGE, null,
                        buttonRowObjects_,
                        null);
            }
        } else if (resouse == A3) {
            if (A3.getText().trim().equals(correctArray[nQ])) {
                nscore = nscore + scoreCurrent;
                changePro(true);
            } else {
                JOptionPane.showOptionDialog(null, "Your answer is wrong", "Oops", JOptionPane.OK_OPTION, JOptionPane.WARNING_MESSAGE, null,
                        buttonRowObjects_,
                        null);
            }
        } else if (resouse == A4) {
            if (A4.getText().trim().equals(correctArray[nQ])) {
                nscore = nscore + scoreCurrent;
                changePro(true);
            } else {
                JOptionPane.showOptionDialog(null, "Your answer is wrong", "Oops", JOptionPane.OK_OPTION, JOptionPane.WARNING_MESSAGE, null,
                        buttonRowObjects_,
                        null);
            }
        }
        if (clickTime == 2) {
            changePro(false);

        }

    }

    /**
     * This is the initialize the resulting UI
     */
    private void initResultUI() {
        Question.setText("                                    ");
        finish.setFont(bigFont);
        finish.setText("Your total score is " + nscore + ".");
        lastPanel.add(finish);
        remove(lastPanel);
        remove(cPanel);
        add(lastPanel, BorderLayout.CENTER);
        lastPanel.setVisible(true);
    }

    /**
     * @param mode
     */
    private void changeQuestionUI(int mode) {
        this.nMode = mode;
        modelPanel.setVisible(false);
        add(cPanel, BorderLayout.CENTER);
        cPanel.setVisible(true);
        bottom.setVisible(true);
        Question.setVisible(true);

        switch (mode) {
            case 0:
                questionArray = Arrays.copyOfRange(allQuestionArray, 0, 4);
                correctArray = Arrays.copyOfRange(allCorrectArray, 0, 4);
                answerArray = Arrays.copyOfRange(allAnswerArray, 0, 4);


                break;

            case 1:
                questionArray = Arrays.copyOfRange(allQuestionArray, 4, 8);
                correctArray = Arrays.copyOfRange(allCorrectArray, 4, 8);
                answerArray = Arrays.copyOfRange(allAnswerArray, 4, 8);

                break;
            case 2:
                questionArray = Arrays.copyOfRange(allQuestionArray, 8, 10);
                correctArray = Arrays.copyOfRange(allCorrectArray, 8, 10);
                answerArray = Arrays.copyOfRange(allAnswerArray, 8, 10);
                break;

        }
        initData();
    }

    /**
     * This method implements the method to listen to different buttons and give different response.
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == A1) {
            totalScore(e.getSource());
        } else if (e.getSource() == A2) {
            totalScore(e.getSource());
        } else if (e.getSource() == A3) {
            totalScore(e.getSource());
        } else if (e.getSource() == A4) {
            totalScore(e.getSource());
        } else if (e.getSource() == B1) {
            changeQuestionUI(0);
        } else if (e.getSource() == B2) {
            changeQuestionUI(1);
        } else if (e.getSource() == B3) {
            changeQuestionUI(2);
        }
    }

}